package com.alibaba.citrus.cr.sales.plan.facade.service.statistics;

import com.alibaba.acm.shaded.com.google.common.collect.Lists;
import com.alibaba.citrus.cr.common.annotation.FacadeInvoker;
import com.alibaba.citrus.cr.common.exception.FacadeException;
import com.alibaba.citrus.cr.common.util.DateUtils;
import com.alibaba.citrus.cr.sales.plan.dto.api.request.SalesPlanAdjustDetailSubTotalRequest;
import com.alibaba.citrus.cr.sales.plan.dto.api.response.DepartmentResponse;
import com.alibaba.citrus.cr.sales.plan.dto.api.response.SalesPlanSubTotalResponse;
import com.alibaba.citrus.cr.sales.plan.model.SalesPlanReportAuditStatusEnum;
import com.alibaba.citrus.cr.sales.plan.model.SalesPlanReportStatusEnum;
import com.alibaba.citrus.cr.sales.plan.model.enums.ContractDataSourceEnum;
import com.alibaba.citrus.cr.sales.plan.model.enums.ContractStatDimensionEnum;
import com.alibaba.citrus.cr.sales.plan.model.enums.SalesPlanModelEnum;
import com.alibaba.citrus.cr.sales.plan.model.enums.SalesPlanStatusEnum;
import com.alibaba.citrus.cr.sales.plan.model.enums.SalesStatBizTypeEnum;
import com.alibaba.citrus.cr.sales.plan.model.enums.StatPoolTypeEnum;
import com.alibaba.citrus.cr.sales.plan.repository.SalesPlanAdjustDetailRepository;
import com.alibaba.citrus.cr.sales.plan.repository.SalesPlanLineRepository;
import com.alibaba.citrus.cr.sales.plan.repository.SalesPlanRepository;
import com.alibaba.citrus.cr.sales.plan.repository.SalesPlanScItemStatRepository;
import com.alibaba.citrus.cr.sales.plan.sdo.SalesPlanReportSDO;
import com.alibaba.citrus.cr.sales.plan.sdo.SalesPlanStatScItemSDO;
import com.alibaba.citrus.cr.sales.plan.api.salesplan.report.SalesPlanReportQueryService;
import com.alibaba.citrus.cr.sales.plan.api.statistics.SalesPlanScItemStatQueryService;
import com.alibaba.citrus.cr.sales.plan.dto.api.request.DimensionDTO;
import com.alibaba.citrus.cr.sales.plan.dto.api.request.PageQueryDepartmentTaskCountRequest;
import com.alibaba.citrus.cr.sales.plan.dto.api.request.PageQueryPlanScItemStatRequest;
import com.alibaba.citrus.cr.sales.plan.dto.api.request.QueryPlanScItemStatRequest;
import com.alibaba.citrus.cr.sales.plan.dto.api.request.QuerySalesPlanRequest;
import com.alibaba.citrus.cr.sales.plan.dto.api.request.SalesPlanReportQueryRequest;
import com.alibaba.citrus.cr.sales.plan.dto.api.request.SalesPlanReportRequest;
import com.alibaba.citrus.cr.sales.plan.dto.api.request.SalesPlanScItemStatSubTotalRequest;
import com.alibaba.citrus.cr.sales.plan.facade.service.SalesPlanCommonService;
import com.alibaba.cz.base.tool.Nullable;
import com.alibaba.cz.base.tool.StringUtil;
import com.alibaba.cz.base.tool.log.Log;
import com.alibaba.cz.base.tool.message.ErrorMessage;
import com.alibaba.cz.base.tool.page.PageResult;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.lattice2.epoch.sdk.model.Result;
import com.epoch.app.bcorder.model.dto.*;
import com.epoch.app.bcorder.sales_plan.contract.dto.LoadListGroupByCrmCompanyCategoryRequest;
import com.epoch.app.bcorder.sales_plan.contract.dto.PageQueryContractListResponse;
import com.epoch.app.bcorder.sales_plan.contract.dto.SubTotalCompanyCrmContractCountRequest;
import com.epoch.app.bcorder.sales_plan.contract.model.Contract;
import com.epoch.app.bcorder.sales_plan.contract.service.ContractService;
import com.epoch.app.bcorder.sales_plan.planscitem.dto.LoadPlanScItemListRequest;
import com.epoch.app.bcorder.sales_plan.planscitem.model.PlanScItem;
import com.epoch.app.bcorder.sales_plan.planscitem.service.PlanScItemService;
import com.epoch.app.bcorder.sales_plan.planscitemextend.dto.SubTotalCompanyReturnCountRequest;
import com.epoch.app.bcorder.sales_plan.planscitemextend.dto.SubTotalCompanyReturnCountResponse;
import com.epoch.app.bcorder.sales_plan.planscitemextend.service.PlanScItemExtendService;
import com.epoch.app.bcorder.sales_plan.salesplandetail.dto.SubTotalSalesPlanLineRequest;
import com.epoch.app.bcorder.service.BaseDataService;
import com.epoch.app.bcorder.service.UnifiedInventoryService;
import com.epoch.app.crunifiedinventory.model.dto.GetCompanyInventoryRequest;
import com.epoch.app.crunifiedinventory.model.dto.WarehouseInventory;
import com.epoch.app.crunifiedinventory.service.CrUnifiedInventoryService;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.collections4.MapUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.IntStream;

/**
 * @author yuhailin
 * @description:
 * @date 2021-09-27 10:37
 */
@Component
public class SalesPlanScItemStatQueryServiceImpl implements SalesPlanScItemStatQueryService {

    private final Log log = Log.getLogger(SalesPlanScItemStatQueryServiceImpl.class);

    @Resource
    private SalesPlanScItemStatRepository salesPlanScItemStatRepository;

    @Resource
    private SalesPlanCommonService salesPlanCommonService;

    @Resource
    private SalesPlanReportQueryService salesPlanReportQueryService;

    @Resource
    private BaseDataService baseDataService;

    @Resource
    private UnifiedInventoryService unifiedInventoryService;

    @Resource
    private CrUnifiedInventoryService crUnifiedInventoryService;

    @Resource
    private SalesPlanRepository salesPlanRepository;

    @Resource
    private PlanScItemService planScItemService;

    @Resource
    private ContractService contractService;

    @Resource
    private PlanScItemExtendService planScItemExtendService;

    @Resource
    private SalesPlanLineRepository salesPlanLineRepository;

    @Resource
    private SalesPlanAdjustDetailRepository salesPlanAdjustDetailRepository;

    @FacadeInvoker
    @Override
    public Result<PageResult<List<SalesPlanStatScItemSDO>>> pageQueryPlanScItemList(PageQueryPlanScItemStatRequest pageQueryPlanScItemStatRequest) {
        com.alibaba.citrus.cr.sales.plan.sdo.SalesPlanSDO salesPlan = salesPlanCommonService.checkSalesPlan(pageQueryPlanScItemStatRequest.getPlanId());
        enichQueryPlanScItemStatRequest(pageQueryPlanScItemStatRequest,salesPlan);
        PageResult<List<SalesPlanStatScItemSDO>> pageResult = salesPlanScItemStatRepository.pageQueryPlanScItemList(pageQueryPlanScItemStatRequest);
        pageResultListConverter(pageResult, pageQueryPlanScItemStatRequest);
        //货品维度和类目维度查询库存、crm合同量,组织维度查询合同量
        refreshStockAndCrmContract(pageResult, pageQueryPlanScItemStatRequest);
        return Result.success(pageResult);
    }

    /**
     * 填充库存，crm合同量
     *
     * @param pageResult
     * @param pageQueryPlanScItemStatRequest
     */
    private void refreshStockAndCrmContract(PageResult<List<SalesPlanStatScItemSDO>> pageResult, PageQueryPlanScItemStatRequest pageQueryPlanScItemStatRequest) {
        // 货品维度查询库存，类目维度查询货品再查库存
        List<SalesPlanStatScItemSDO> content = pageResult.getContent();
        if (CollectionUtils.isEmpty(content)) {
            return;
        }
        // 根据planId查询分子公司编码
        String planId = pageQueryPlanScItemStatRequest.getPlanId();
        QuerySalesPlanRequest querySalesPlanRequest = new QuerySalesPlanRequest();
        querySalesPlanRequest.setId(planId);
        com.alibaba.citrus.cr.sales.plan.sdo.SalesPlanSDO salesPlanSDO  = salesPlanRepository.load(querySalesPlanRequest);
        if (Objects.isNull(salesPlanSDO)) {
            return;
        }
        String planTime = salesPlanSDO.getPlanTime();
        String orgBusinessUnitCode = salesPlanSDO.getOrgBusinessUnitCode();
        Integer poolType = pageQueryPlanScItemStatRequest.getPoolType();

        // 公司类目维度
        if (StatPoolTypeEnum.CATEGORY.getPoolType().equals(poolType)) {
            long start = System.currentTimeMillis();
            log.info("查询类目汇总公司库存 start:{}", start);
            // 存在货品没有类目的情况，这种货品也要查库存的
            List<SalesPlanStatScItemSDO> filterContent = content.stream()
                    .filter(salesPlanStatScItemSDO -> StringUtils.isNotBlank(salesPlanStatScItemSDO.getScItemCategoryId())).collect(Collectors.toList());

            // 根据类目id转map
            Map<String, SalesPlanStatScItemSDO> salesPlanStatScItemSDOMap = filterContent.stream().collect(Collectors.toMap(SalesPlanStatScItemSDO::getScItemCategoryId, o -> o, (a, b) -> a));

            Map<String, String> stockMap = new HashMap<>();
            // 查找仓库
            List<String> warehouseIdList = fetchWarehouseId(orgBusinessUnitCode);
            for (String scItemCategoryId : salesPlanStatScItemSDOMap.keySet()) {
                // 根据类目查货品ids
                SearchScItemRequest searchScItemRequest = new SearchScItemRequest();
                searchScItemRequest.setPageNum(1);
                searchScItemRequest.setPageSize(2000);
                Map<String, List<String>> searchReqDTOMap = new HashMap<>();
                searchReqDTOMap.put("leafCategoryIdList", Lists.newArrayList(scItemCategoryId));
                searchScItemRequest.setSearchReqDTO(searchReqDTOMap);
                Result<List<ScItemSDO>> searchScItemResult = baseDataService.searchScItem(searchScItemRequest);
                if (null == searchScItemResult || !searchScItemResult.isSuccess()) {
                    throw new FacadeException("OTS-02-004-01-15-038");
                }
                List<String> scItemIdList = searchScItemResult.getResult().stream().map(ScItemSDO::getScItemId).collect(Collectors.toList());
                // 查询该类目维度下的所有货品的库存map，key:货品id; value:库存
                Map<String, String> stockByCategoryMap = new HashMap<>();
                try {
                    stockByCategoryMap = getStockForCompany(warehouseIdList, scItemIdList);
                } catch (Exception e) {
                    log.error("月度计划查询货品库存异常", e);
                }
                BigDecimal inventory = new BigDecimal(0);
                // stockMap求和，就是该类目下的库存总量
                if (MapUtils.isNotEmpty(stockByCategoryMap)) {
                    for (String scItemId : stockByCategoryMap.keySet()) {
                        String str = stockByCategoryMap.get(scItemId);
                        inventory = inventory.add(new BigDecimal(str));
                    }
                }
                String inventoryStr = inventory.toString();
                stockMap.put(scItemCategoryId, inventoryStr);
            }
            log.info("查询类目汇总公司库存 总耗时:{}", System.currentTimeMillis() - start);

            //List<String> categoryIdList = salesPlanStatScItemSDOMap.keySet().stream().collect(Collectors.toList());
            Map<String, Long> contractCountMap = getCrmContractByCategory(planTime, orgBusinessUnitCode, null);

            content.forEach(salesPlanStatScItemSDO -> {
                String scItemCategoryId = salesPlanStatScItemSDO.getScItemCategoryId();
                String inventory = stockMap.get(scItemCategoryId);
                salesPlanStatScItemSDO.setInventoryStr(inventory);
                Long contractCount = contractCountMap.get(scItemCategoryId);
                salesPlanStatScItemSDO.setCrmContractCount(contractCount==null?0L:contractCount);
            });
            pageResult.setContent(content);
        }
        // 公司货品维度
        else if (StatPoolTypeEnum.SC_ITEM.getPoolType().equals(poolType)) {
            long start = System.currentTimeMillis();
            log.info("查询货品汇总公司库存 start:{}", start);
            List<String> scItemIdList = content.stream().map(SalesPlanStatScItemSDO::getScItemId).collect(Collectors.toList());
            // 查询货品下的库存map，key：货品id；value：库存
            Map<String, String> stockMap = new HashMap<>();
            try {
                stockMap = getStockForCompany(fetchWarehouseId(orgBusinessUnitCode), scItemIdList);
            } catch (Exception e) {
                log.error("月度计划查询货品库存异常", e);
            }
            log.info("查询货品汇总公司库存 总耗时:{}", System.currentTimeMillis() - start);

            Map<String, Long> contractCountMap = getCrmContractByScItem(planTime, orgBusinessUnitCode, scItemIdList);

            if (MapUtils.isNotEmpty(stockMap)) {
                Map<String, String> finalStockMap = stockMap;
                content.forEach(salesPlanStatScItemSDO -> {
                    String scItemId = salesPlanStatScItemSDO.getScItemId();
                    String availableQuantity = finalStockMap.get(scItemId);
                    salesPlanStatScItemSDO.setInventoryStr(availableQuantity);
                    Long contractCount = contractCountMap.get(scItemId);
                    salesPlanStatScItemSDO.setCrmContractCount(contractCount==null?0L:contractCount);
                });
            }
            pageResult.setContent(content);
        }
        // 公司维度
        else if(StatPoolTypeEnum.ORGANIZATION.getPoolType().equals(poolType) && StringUtils.isBlank(pageQueryPlanScItemStatRequest.getParentId())){
            Long contractCount = getCrmContractByCompany(planTime, orgBusinessUnitCode);
            content.forEach(salesPlanStatScItemSDO -> {
                salesPlanStatScItemSDO.setCrmContractCount(contractCount);
            });
        }
    }

    /**
     * 1、根据公司查销售组织
     * 2、根据销售组织查仓库
     * 3、根据仓库+货品id查仓库里的库存
     * 4、汇总为公司级别
     *
     * @param warehouseIdList 仓库idList
     * @param scItemIdList    货品idList
     * @return Map(货品id, 公司库存)
     */
    private Map<String, String> getStockForCompany(List<String> warehouseIdList, List<String> scItemIdList) {
        if (CollectionUtils.isEmpty(scItemIdList)) {
            return new HashMap<>();
        }
        // 3、根据仓库+货品id查仓库里的库存
        GetCompanyInventoryRequest getCompanyInventoryRequest = new GetCompanyInventoryRequest();
        getCompanyInventoryRequest.setGoodsIds(scItemIdList);
        getCompanyInventoryRequest.setWarehouseAreaIdList(warehouseIdList);
        long start = System.currentTimeMillis();
        log.info("调用公司库存接口 start:{}", start);
        Result<List<WarehouseInventory>> listWarehouseStock = crUnifiedInventoryService.getCompanyInventory(getCompanyInventoryRequest);
        log.info("调用公司库存接口 end, 总耗时:{}", System.currentTimeMillis() - start);
        if (null == listWarehouseStock || !listWarehouseStock.isSuccess()) {
            throw new FacadeException("OTS-02-004-01-15-036");
        }
        List<WarehouseInventory> listWarehouseStockResult = listWarehouseStock.getResult();
        if (CollectionUtils.isEmpty(listWarehouseStockResult)) {
            throw new FacadeException("OTS-02-004-01-15-037");
        }
        // 根据货品id分组  每一个key代表一个货品下的所有仓库的库存量 陈慕已经汇总，一个货品只有一个库存量（聚合所有仓库）
        Map<String, List<WarehouseInventory>> listMap = listWarehouseStockResult.stream().collect(Collectors.groupingBy(WarehouseInventory::getGoodsId));
        Map<String, String> result = new HashMap<>();
        for (String scItemId : listMap.keySet()) {
            List<WarehouseInventory> warehouseInventoryList = listMap.get(scItemId);
            if (CollectionUtils.isEmpty(warehouseInventoryList)) {
                continue;
            }
            WarehouseInventory warehouseInventory = warehouseInventoryList.get(0);
            String availableQuantityFormat = warehouseInventory.getAvailableQuantityFormat();
            // 一个货品在一个仓库只有一个库存
            result.put(scItemId, availableQuantityFormat);
        }
        return result;
    }

    private List<String> fetchWarehouseId(String companyCode) {
        long start = System.currentTimeMillis();
        // 1、获取分子公司下的销售组织
        GetOrganizationSelectsRequest getOrganizationSelectsRequest = new GetOrganizationSelectsRequest();
        getOrganizationSelectsRequest.setParentId(companyCode);

        log.info("查询业务单元下的销售组织请求参数：{}", JSON.toJSONString(getOrganizationSelectsRequest));
        GetOrganizationSelectsResponse organizationSelects = baseDataService.getOrganizationSelects(getOrganizationSelectsRequest);
        log.info("查询业务单元下的销售组织返回结果：{}", JSON.toJSONString(organizationSelects));
        if (null == organizationSelects) {
            throw new FacadeException("OTS-02-004-01-15-033");
        }
        List orgResult = organizationSelects.getResult();
        if (CollectionUtils.isEmpty(orgResult)) {
            throw new FacadeException("OTS-02-004-01-15-034");
        }
        List<Map> mapList = JSONObject.parseArray(JSON.toJSONString(orgResult), Map.class);
        List<String> orgIdList = mapList.stream().map(map -> map.get("value").toString()).collect(Collectors.toList());
        // 2、根据销售组织查仓库
        SearchCargoZoneListRequest searchCargoZoneListRequest = new SearchCargoZoneListRequest();
        searchCargoZoneListRequest.setModel(3);
        searchCargoZoneListRequest.setStatus(1);
        searchCargoZoneListRequest.setSize(1000);
        searchCargoZoneListRequest.setSaleOrgIdList(orgIdList);
        log.info("查询销售组织下的仓库请求参数：{}", JSON.toJSONString(searchCargoZoneListRequest));
        SearchCargoZoneListResponse searchCargoZoneListResponse = unifiedInventoryService.searchCargoZoneList(searchCargoZoneListRequest);
        log.info("查询销售组织下的仓库返回结果：{}", JSON.toJSONString(searchCargoZoneListResponse));
        if (null == searchCargoZoneListResponse || searchCargoZoneListResponse.getTotal() <= 0
                || CollectionUtils.isEmpty(searchCargoZoneListResponse.getResult())) {
            throw new FacadeException("OTS-02-004-01-15-035");
        }
        List<WarehouseInfo> warehouseInfoList = searchCargoZoneListResponse.getResult();
        log.info("获取仓库耗时:{}", System.currentTimeMillis() - start);
        return warehouseInfoList.stream().map(WarehouseInfo::getId).collect(Collectors.toList());
    }

    /**
     * 获取crm合同量  公司货品维度
     *
     * @param planTime   计划年月时间戳
     * @param orgBusinessUnitCode 分子公司组织id
     * @param scItemIdList 货品idList
     * @return
     */
    private Map<String, Long> getCrmContractByScItem(String planTime, String orgBusinessUnitCode, List<String> scItemIdList){
        com.epoch.app.bcorder.sales_plan.contract.dto.PageQueryContractListRequest pageQueryContractListRequest = new com.epoch.app.bcorder.sales_plan.contract.dto.PageQueryContractListRequest();
        pageQueryContractListRequest.setContractYear(DateUtils.toDateStr(Long.valueOf(planTime),"yyyy"));
        pageQueryContractListRequest.setOrgBusinessUnitCode(orgBusinessUnitCode);
        pageQueryContractListRequest.setScItemIds(scItemIdList);
        pageQueryContractListRequest.setType(ContractStatDimensionEnum.COMPANY_SC_ITEM.getCode());
        pageQueryContractListRequest.setDataSource(ContractDataSourceEnum.CRM.getCode());
        pageQueryContractListRequest.setSize(1000);
        PageQueryContractListResponse contractListResponse = contractService.pageQueryContractList(pageQueryContractListRequest);
        String month = DateUtils.toDateStr(Long.valueOf(planTime),"MM");
        Map<String, Long> result = Nullable.stream(contractListResponse.getResult()).collect(Collectors.toMap(Contract::getScItemId, x->getContractCount(month,x),(v1, v2)->v1));
        return result;
    }

    /**
     * 获取crm合同量  公司类目维度
     *
     * @param planTime   计划年月时间戳
     * @param orgBusinessUnitCode 分子公司组织id
     * @param categoryIdList 类目idList
     * @return
     */
    private Map<String, Long> getCrmContractByCategory(String planTime, String orgBusinessUnitCode, List<String> categoryIdList){
        LoadListGroupByCrmCompanyCategoryRequest queryCrmCompanyCategoryRequest = new LoadListGroupByCrmCompanyCategoryRequest();
        queryCrmCompanyCategoryRequest.setContractYear(DateUtils.toDateStr(Long.valueOf(planTime),"yyyy"));
        queryCrmCompanyCategoryRequest.setOrgBusinessUnitCode(orgBusinessUnitCode);
        queryCrmCompanyCategoryRequest.setScItemCategoryIdList(categoryIdList);
//        queryCrmCompanyCategoryRequest.setType(ContractStatDimensionEnum.COMPANY_SC_ITEM.getCode());
//        queryCrmCompanyCategoryRequest.setDataSource(ContractDataSourceEnum.CRM.getCode());
        queryCrmCompanyCategoryRequest.setStart(0);
        queryCrmCompanyCategoryRequest.setLimit(1000);
        Result<List<Contract>> contractListResponse = contractService.loadListGroupByCrmCompanyCategory(queryCrmCompanyCategoryRequest);
        String month = DateUtils.toDateStr(Long.valueOf(planTime),"MM");
        Map<String, Long> result = Nullable.stream(contractListResponse.getResult()).collect(Collectors.toMap(Contract::getScItemCategoryId, x->getContractCount(month,x),(v1, v2)->v1));
        return result;
    }

    /**
     * 获取crm合同量  公司维度
     *
     * @param planTime   计划年月时间戳
     * @param orgBusinessUnitCode 分子公司组织id
     * @return
     */
    private Long getCrmContractByCompany(String planTime, String orgBusinessUnitCode){
        SubTotalCompanyCrmContractCountRequest subTotalCompanyCrmContractCountRequest = new SubTotalCompanyCrmContractCountRequest();
        subTotalCompanyCrmContractCountRequest.setContractYear(DateUtils.toDateStr(Long.valueOf(planTime),"yyyy"));
        subTotalCompanyCrmContractCountRequest.setOrgBusinessUnitCode(orgBusinessUnitCode);
//        subTotalCompanyCrmContractCountRequest.setType(ContractStatDimensionEnum.COMPANY_SC_ITEM.getCode());
//        subTotalCompanyCrmContractCountRequest.setDataSource(ContractDataSourceEnum.CRM.getCode());
        Result<Contract> response = contractService.subTotalCompanyCrmContractCount(subTotalCompanyCrmContractCountRequest);
        String month = DateUtils.toDateStr(Long.valueOf(planTime),"MM");
        Long contractCount = getContractCount(month,response.getResult());
        return contractCount;
    }

    public Long getContractCount(String month, Contract contract){
        Integer amount = new Integer(0);
        switch (month){
            case "01" :
                amount = contract.getJanQuantity();
                break;
            case "02" :
                amount = contract.getFebQuantity();
                break;
            case "03" :
                amount = contract.getMarQuantity();
                break;
            case "04" :
                amount = contract.getAprQuantity();
                break;
            case "05" :
                amount = contract.getMayQuantity();
                break;
            case "06" :
                amount = contract.getJuneQuantity();
                break;
            case "07" :
                amount = contract.getJulyQuantity();
                break;
            case "08" :
                amount = contract.getAugQuantity();
                break;
            case "09" :
                amount = contract.getSeptQuantity();
                break;
            case "10" :
                amount = contract.getOctQuantity();
                break;
            case "11" :
                amount = contract.getNovQuantity();
                break;
            case "12" :
                amount = contract.getDecQuantity();
                break;
        }
        return amount!=null?Long.valueOf(amount):0L;
    }

    private void enichQueryPlanScItemStatRequest(PageQueryPlanScItemStatRequest pageQueryPlanScItemStatRequest,com.alibaba.citrus.cr.sales.plan.sdo.SalesPlanSDO salesPlan) {
        if (StatPoolTypeEnum.ORGANIZATION.getPoolType().equals(pageQueryPlanScItemStatRequest.getPoolType())
                && StringUtils.isNotBlank(pageQueryPlanScItemStatRequest.getParentId())) {
            pageQueryPlanScItemStatRequest.setBizType(null);
            pageQueryPlanScItemStatRequest.setBizId(null);
        } else {
            pageQueryPlanScItemStatRequest.setParentId(null);
//            com.alibaba.citrus.cr.sales.plan.sdo.SalesPlanSDO salesPlan = salesPlanCommonService.checkSalesPlan(pageQueryPlanScItemStatRequest.getPlanId());
            DimensionDTO dimension = salesPlanCommonService.checkBizType(salesPlan, pageQueryPlanScItemStatRequest);
            pageQueryPlanScItemStatRequest.setBizType(dimension.getBizType());
            pageQueryPlanScItemStatRequest.setBizId(dimension.getBizId());
        }
    }

    private void pageResultListConverter(PageResult<List<SalesPlanStatScItemSDO>> listPageResult, PageQueryPlanScItemStatRequest request) {
        if (CollectionUtils.isEmpty(listPageResult.getContent())) {
            return;
        }
        // 暂时只要求组织汇总要求
        if (!StatPoolTypeEnum.ORGANIZATION.getPoolType().equals(request.getPoolType())) {
            return;
        }
        listPageResult.getContent().forEach(scItemSDO -> {
            scItemSDO.setOrganizationType(SalesStatBizTypeEnum.match(scItemSDO.getBizType()).getOrganizationType());
            scItemSDO.setIsAudit(false);
            //审批状态
            if (scItemSDO.getBizType() != null && StringUtil.isNotEmpty(scItemSDO.getBizId())) {
                refreshSalesPlanStatScItemSDO(scItemSDO, request);
            }
        });
        List<String> reportOrderIdList = listPageResult.getContent().stream().map(SalesPlanStatScItemSDO::getReportOrderId).filter(StringUtils::isNotBlank).collect(Collectors.toList());
        SalesPlanReportRequest reportRequest = new SalesPlanReportRequest();
        reportRequest.setReportOrderIdList(reportOrderIdList);
        reportRequest.setOperatorId(request.getOperatorId());
        Result<Map<String, Boolean>> reportMap = salesPlanReportQueryService.batchVerifyAuditPermission(reportRequest);
        if (null == reportMap || MapUtils.isEmpty(reportMap.getResult())) {
            return;
        }
        // 填充审批状态信息
        refreshSalesPlanStatScItemSDO(listPageResult.getContent(), reportMap.getResult());
    }

    @FacadeInvoker
    @Override
    public Result<PageResult<List<SalesPlanStatScItemSDO>>> queryDepartmentTaskCountList(PageQueryDepartmentTaskCountRequest queryDepartmentTaskCountRequest) {
        return Result.success(salesPlanScItemStatRepository.queryDepartmentTaskCountList(queryDepartmentTaskCountRequest));
    }

    @FacadeInvoker
    @Override
    public Result<PageResult<List<SalesPlanStatScItemSDO>>> batchQueryPlanScItemByBizId(QueryPlanScItemStatRequest queryPlanScItemStatRequest) {
        return Result.success(salesPlanScItemStatRepository.batchQueryPlanScItemByBizId(queryPlanScItemStatRequest));
    }

    @FacadeInvoker
    @Override
    public Result<List<SalesPlanStatScItemSDO>> queryPlanScItemByPlanId(QueryPlanScItemStatRequest queryPlanScItemStatRequest) {
        return Result.success(salesPlanScItemStatRepository.queryPlanScItemByPlanId(queryPlanScItemStatRequest));
    }

    @FacadeInvoker
    @Override
    public Result<SalesPlanStatScItemSDO> queryPlanScItemById(QueryPlanScItemStatRequest queryPlanScItemStatRequest) {
        return Result.success(salesPlanScItemStatRepository.getSalesPlanScItem(queryPlanScItemStatRequest));
    }

    @FacadeInvoker
    @Override
    public Result<SalesPlanStatScItemSDO> queryPlanScItemDepartmentTaskCount(PageQueryPlanScItemStatRequest pageQueryDepartmentTaskCountRequest) {
        pageQueryDepartmentTaskCountRequest.setPlanId(String.valueOf(pageQueryDepartmentTaskCountRequest.getPlanId()));
        pageQueryDepartmentTaskCountRequest.setBizType(SalesStatBizTypeEnum.SALES_DEPARTMENT.getBizType());
        PageResult<List<SalesPlanStatScItemSDO>> pageResult = salesPlanScItemStatRepository.pageQueryPlanScItemList(pageQueryDepartmentTaskCountRequest);
        List<SalesPlanStatScItemSDO> firstPageContent = pageResult.getContent();
        int totalPages = (int) pageResult.getTotalPages();
        if (totalPages >= 1) {
            IntStream.range(2, totalPages).forEach(page -> {
                pageQueryDepartmentTaskCountRequest.setPage(page);
                List<SalesPlanStatScItemSDO> salesPlanScItemStatSDOList = salesPlanScItemStatRepository.pageQueryPlanScItemList(pageQueryDepartmentTaskCountRequest).getContent();
                firstPageContent.addAll(salesPlanScItemStatSDOList);
            });
        }
        return Result.success(doCalculate(firstPageContent));
    }

    @FacadeInvoker
    @Override
    public Result<SalesPlanSubTotalResponse> subTotalSalesPlanScItemStat(SalesPlanScItemStatSubTotalRequest salesPlanScItemStatSubTotalRequest) {
        com.alibaba.citrus.cr.sales.plan.sdo.SalesPlanSDO salesPlan = salesPlanCommonService.checkSalesPlan(salesPlanScItemStatSubTotalRequest.getPlanId());
        PageQueryPlanScItemStatRequest pageQueryPlanScItemStatRequest = new PageQueryPlanScItemStatRequest();
        BeanUtils.copyProperties(salesPlanScItemStatSubTotalRequest,pageQueryPlanScItemStatRequest);
        enichQueryPlanScItemStatRequest(pageQueryPlanScItemStatRequest,salesPlan);
        SalesPlanScItemStatSubTotalRequest subTotalRequest = new SalesPlanScItemStatSubTotalRequest();
        BeanUtils.copyProperties(pageQueryPlanScItemStatRequest,subTotalRequest);
        subTotalRequest.setIsAdjustCount(false);
        SalesPlanSubTotalResponse salesPlanSubTotalResponse = salesPlanScItemStatRepository.subTotalSalesPlanScItemStat(subTotalRequest);

        BigDecimal discount = (new BigDecimal(100).subtract(salesPlan.getEstimateDiscount())).divide(new BigDecimal(100),2,BigDecimal.ROUND_HALF_UP);
        List<String> queryScItemIdList = CollectionUtils.isNotEmpty(subTotalRequest.getScItemIdList())?subTotalRequest.getScItemIdList():null;
        List<String> queryScItemLeafCategoryId = CollectionUtils.isNotEmpty(subTotalRequest.getScItemLeafCategoryIdList())?subTotalRequest.getScItemLeafCategoryIdList():null;
        SubTotalSalesPlanLineRequest queryDimension = getQueryDimension(subTotalRequest);
        if(salesPlanSubTotalResponse.getMonthCount()!= null){
            //调整汇总
            if(salesPlanScItemStatSubTotalRequest.getIsAdjustCount()){
                //合计总调整量
                SalesPlanAdjustDetailSubTotalRequest subTotalAdjustDetailRequest = new SalesPlanAdjustDetailSubTotalRequest();
                if(Objects.nonNull(queryDimension)){
                    BeanUtils.copyProperties(queryDimension, subTotalAdjustDetailRequest);
                    subTotalAdjustDetailRequest.setManageEmployeeId(CollectionUtils.isNotEmpty(queryDimension.getManageEmployeeIdList())?(String)queryDimension.getManageEmployeeIdList().get(0):null);
                }
                BeanUtils.copyProperties(subTotalRequest, subTotalAdjustDetailRequest);
                subTotalAdjustDetailRequest.setAdjustId(salesPlanScItemStatSubTotalRequest.getAdjustId());
                subTotalAdjustDetailRequest.setScItemIdList(queryScItemIdList);
                subTotalAdjustDetailRequest.setScItemLeafCategoryIdList(queryScItemLeafCategoryId);
                subTotalAdjustDetailRequest.setAdjust(true);
                subTotalAdjustDetailRequest.setPlanId(null);
                SalesPlanSubTotalResponse subTotalAdjustDetailResponse = salesPlanAdjustDetailRepository.subTotalSalesPlanAdjustDetail(subTotalAdjustDetailRequest);
                salesPlanSubTotalResponse.setAdjustCount(subTotalAdjustDetailResponse.getAdjustCount());
                salesPlanSubTotalResponse.setBeforeAdjustMoney(subTotalAdjustDetailResponse.getBeforeAdjustMoney());
                if(subTotalAdjustDetailResponse.getBeforeAdjustMoney()!=null){
                    BigDecimal adjustMoney = new BigDecimal(subTotalAdjustDetailResponse.getBeforeAdjustMoney()).multiply(discount);
                    salesPlanSubTotalResponse.setAdjustMoney(adjustMoney.longValue());
                }
                //初始任务量
                SubTotalSalesPlanLineRequest subTotalSalesPlanLineRequest = getSubTotalSalesPlanLineRequest(subTotalRequest,queryDimension);
                SalesPlanSubTotalResponse salesPlanSubTotalAdjustResponse = salesPlanLineRepository.subTotalSalesPlanLine(subTotalSalesPlanLineRequest);
                salesPlanSubTotalResponse.setInitTaskCount(salesPlanSubTotalAdjustResponse.getInitTaskCount());
                salesPlanSubTotalResponse.setInitBeforeTaskMoney(salesPlanSubTotalAdjustResponse.getInitBeforeTaskMoney());
                if(salesPlanSubTotalAdjustResponse.getInitBeforeTaskMoney()!=null){
                    BigDecimal initTaskMoney = new BigDecimal(salesPlanSubTotalAdjustResponse.getInitBeforeTaskMoney()).multiply(discount);
                    salesPlanSubTotalResponse.setInitTaskMoney(initTaskMoney.longValue());
                }
             //计划汇总
            }else{
                //合计总调整量
                SubTotalSalesPlanLineRequest subTotalSalesPlanLineRequest = getSubTotalSalesPlanLineRequest(subTotalRequest,queryDimension);
                SalesPlanSubTotalResponse salesPlanSubTotalAdjustResponse = salesPlanLineRepository.subTotalSalesPlanLine(subTotalSalesPlanLineRequest);
                salesPlanSubTotalResponse.setAdjustCount(salesPlanSubTotalAdjustResponse.getAdjustCount());
                salesPlanSubTotalResponse.setBeforeAdjustMoney(salesPlanSubTotalAdjustResponse.getBeforeAdjustMoney());
                salesPlanSubTotalResponse.setAdjustOutboundMoney(salesPlanSubTotalAdjustResponse.getAdjustOutboundMoney());
                if(salesPlanSubTotalResponse.getBeforeAdjustMoney()!=null){
                    BigDecimal adjustMoney = new BigDecimal(salesPlanSubTotalResponse.getBeforeAdjustMoney()).multiply(discount);
                    salesPlanSubTotalResponse.setAdjustMoney(adjustMoney.longValue());
                }
                //初始任务量
                if(salesPlan.getStatus()>= SalesPlanStatusEnum.PUBLISHED.getCode()){
                    salesPlanSubTotalResponse.setInitTaskCount(salesPlanSubTotalAdjustResponse.getInitTaskCount());
                    salesPlanSubTotalResponse.setInitBeforeTaskMoney(salesPlanSubTotalAdjustResponse.getInitBeforeTaskMoney());
                    if(salesPlanSubTotalAdjustResponse.getInitBeforeTaskMoney()!=null){
                        BigDecimal initTaskMoney = new BigDecimal(salesPlanSubTotalAdjustResponse.getInitBeforeTaskMoney()).multiply(discount);
                        salesPlanSubTotalResponse.setInitTaskMoney(initTaskMoney.longValue());
                    }
                }else{
                    salesPlanSubTotalResponse.setInitTaskCount(0);
                    salesPlanSubTotalResponse.setInitBeforeTaskMoney(0L);
                    salesPlanSubTotalResponse.setInitTaskMoney(0L);
                }
            }
            //合计crm回复量
            SubTotalCompanyReturnCountRequest subTotalCompanyReturnCountRequest = new SubTotalCompanyReturnCountRequest();
            BeanUtils.copyProperties(subTotalRequest,subTotalCompanyReturnCountRequest);
            subTotalCompanyReturnCountRequest.setPlanId(Long.valueOf(subTotalRequest.getPlanId()));
            subTotalCompanyReturnCountRequest.setScItemIdList(queryScItemIdList);
            subTotalCompanyReturnCountRequest.setScItemLeafCategoryIdList(queryScItemLeafCategoryId);
            SubTotalCompanyReturnCountResponse subTotalCompanyReturnCountResponse = planScItemExtendService.subTotalCompanyReturnCount(subTotalCompanyReturnCountRequest);
            salesPlanSubTotalResponse.setReturnCount(getMoney(subTotalCompanyReturnCountResponse.getReturnCount()));
            salesPlanSubTotalResponse.setBeforeReturnMoney(getMoney(subTotalCompanyReturnCountResponse.getBeforeReturnMoney()));
            BigDecimal returnMoney = new BigDecimal(salesPlanSubTotalResponse.getBeforeReturnMoney()).multiply(discount);
            salesPlanSubTotalResponse.setReturnMoney(returnMoney.longValue());
            salesPlanSubTotalResponse.setReturnOutboundMoney(getMoney(subTotalCompanyReturnCountResponse.getReturnOutboundMoney()));

            //合计crm合同量
            SubTotalCompanyCrmContractCountRequest subTotalCompanyCrmContractCountRequest = new SubTotalCompanyCrmContractCountRequest();
            subTotalCompanyCrmContractCountRequest.setContractYear(DateUtils.toDateStr(Long.valueOf(salesPlan.getPlanTime()),"yyyy"));
            subTotalCompanyCrmContractCountRequest.setOrgBusinessUnitCode(salesPlan.getOrgBusinessUnitCode());
            subTotalCompanyCrmContractCountRequest.setScItemIdList(queryScItemIdList);
            subTotalCompanyCrmContractCountRequest.setScItemCategoryIdList(queryScItemLeafCategoryId);
            Result<Contract> contractResult = contractService.subTotalCompanyCrmContractCount(subTotalCompanyCrmContractCountRequest);
            Contract contract = contractResult.getResult();
            setSubTotalContractCount(DateUtils.toDateStr(Long.valueOf(salesPlan.getPlanTime()),"MM"),contract,salesPlanSubTotalResponse);
        }
        return Result.success(salesPlanSubTotalResponse);
    }

    private SubTotalSalesPlanLineRequest getSubTotalSalesPlanLineRequest(SalesPlanScItemStatSubTotalRequest subTotalRequest,SubTotalSalesPlanLineRequest queryDimension){
        SubTotalSalesPlanLineRequest subTotalAdjustRequest = new SubTotalSalesPlanLineRequest();
        if(Objects.nonNull(queryDimension)){
            BeanUtils.copyProperties(queryDimension, subTotalAdjustRequest);
        }
        BeanUtils.copyProperties(subTotalRequest, subTotalAdjustRequest);
        subTotalAdjustRequest.setPlanId(Long.valueOf(subTotalRequest.getPlanId()));
        return subTotalAdjustRequest;
    }

    private SubTotalSalesPlanLineRequest getQueryDimension(SalesPlanScItemStatSubTotalRequest subTotalRequest){
        SubTotalSalesPlanLineRequest subTotalSalesPlanLineRequest = new SubTotalSalesPlanLineRequest();
        SalesStatBizTypeEnum byOrganizationType = SalesStatBizTypeEnum.match(subTotalRequest.getBizType());
        if(byOrganizationType == null){
            return null;
        }
        switch (byOrganizationType) {
            case SALESMAN:
                subTotalSalesPlanLineRequest.setManageEmployeeIdList(Lists.newArrayList(subTotalRequest.getBizId()));
                break;
            case SALES_DEPARTMENT:
                subTotalSalesPlanLineRequest.setOrgSalesDepartmentCode(subTotalRequest.getBizId());
                break;
            case SALES_CHANNEL:
                subTotalSalesPlanLineRequest.setOrgSalesChannelCode(subTotalRequest.getBizId());
                break;
            case SALES_ORGANIZATION:
                subTotalSalesPlanLineRequest.setOrgSalesOrganizationCode(subTotalRequest.getBizId());
                break;
            case BUSINESS_UNIT:
                subTotalSalesPlanLineRequest.setOrgBusinessUnitCode(subTotalRequest.getBizId());
                break;
            default:
        }
        return subTotalSalesPlanLineRequest;
    }

    private void setSubTotalContractCount(String month, Contract contract,SalesPlanSubTotalResponse salesPlanSubTotalResponse){
        Long crmMonthContractCount = null;
        Long crmBeforeMonthContractMoney = null;
        Long crmMonthContractMoney = null;
        switch (month){
            case "01" :
                crmMonthContractCount = getCount(contract.getJanQuantity());
                crmBeforeMonthContractMoney = getMoney(contract.getJanTaxIncludedBeforeTax());
                crmMonthContractMoney = getMoney(contract.getJanAmount());
                break;
            case "02" :
                crmMonthContractCount = getCount(contract.getFebQuantity());
                crmBeforeMonthContractMoney = getMoney(contract.getFebTaxIncludedBeforeTax());
                crmMonthContractMoney = getMoney(contract.getFebAmount());
                break;
            case "03" :
                crmMonthContractCount = getCount(contract.getMarQuantity());
                crmBeforeMonthContractMoney = getMoney(contract.getMarTaxIncludedBeforeTax());
                crmMonthContractMoney = getMoney(contract.getMarAmount());
                break;
            case "04" :
                crmMonthContractCount = getCount(contract.getAprQuantity());
                crmBeforeMonthContractMoney = getMoney(contract.getAprTaxIncludedBeforeTax());
                crmMonthContractMoney = getMoney(contract.getAprAmount());
                break;
            case "05" :
                crmMonthContractCount = getCount(contract.getMayQuantity());
                crmBeforeMonthContractMoney = getMoney(contract.getMayTaxIncludedBeforeTax());
                crmMonthContractMoney = getMoney(contract.getMayAmount());
                break;
            case "06" :
                crmMonthContractCount = getCount(contract.getJuneQuantity());
                crmBeforeMonthContractMoney = getMoney(contract.getJuneTaxIncludedBeforeTax());
                crmMonthContractMoney = getMoney(contract.getJuneAmount());
                break;
            case "07" :
                crmMonthContractCount = getCount(contract.getJulyQuantity());
                crmBeforeMonthContractMoney = getMoney(contract.getJulyTaxIncludedBeforeTax());
                crmMonthContractMoney = getMoney(contract.getJulyAmount());
                break;
            case "08" :
                crmMonthContractCount = getCount(contract.getAugQuantity());
                crmBeforeMonthContractMoney = getMoney(contract.getAugTaxIncludedBeforeTax());
                crmMonthContractMoney = getMoney(contract.getAugAmount());
                break;
            case "09" :
                crmMonthContractCount = getCount(contract.getSeptQuantity());
                crmBeforeMonthContractMoney = getMoney(contract.getSeptTaxIncludedBeforeTax());
                crmMonthContractMoney = getMoney(contract.getSeptAmount());
                break;
            case "10" :
                crmMonthContractCount = getCount(contract.getOctQuantity());
                crmBeforeMonthContractMoney = getMoney(contract.getOctTaxIncludedBeforeTax());
                crmMonthContractMoney = getMoney(contract.getOctAmount());
                break;
            case "11" :
                crmMonthContractCount = getCount(contract.getNovQuantity());
                crmBeforeMonthContractMoney = getMoney(contract.getNovTaxIncludedBeforeTax());
                crmMonthContractMoney = getMoney(contract.getNovAmount());
                break;
            case "12" :
                crmMonthContractCount = getCount(contract.getDecQuantity());
                crmBeforeMonthContractMoney = getMoney(contract.getDecTaxIncludedBeforeTax());
                crmMonthContractMoney = getMoney(contract.getDecAmount());
                break;
            default:
                crmMonthContractCount = 0L;
                crmBeforeMonthContractMoney = 0L;
                crmMonthContractMoney = 0L;
        }

        salesPlanSubTotalResponse.setCrmMonthContractCount(crmMonthContractCount);
        salesPlanSubTotalResponse.setCrmBeforeMonthContractMoney(crmBeforeMonthContractMoney);
        salesPlanSubTotalResponse.setCrmMonthContractMoney(crmMonthContractMoney);
    }

    private Long getCount(Integer i){
        if(i == null){
            return 0L;
        }
        return i.longValue();
    }

    private Long getMoney(Long l){
        if(l == null){
            return 0L;
        }
        return l;
    }

    /**
     * 分页查询回退上一级月度计划汇总数据
     *
     * @param request
     * @return
     */
    @Override
    @FacadeInvoker
    public Result<PageResult<List<SalesPlanStatScItemSDO>>> pageQueryBackPlanScItemList(PageQueryPlanScItemStatRequest request) {
        // 检查请求数据
        checkPageQueryPlanScItemStatRequest(request);
        // 获取上一级id
        SalesPlanStatScItemSDO salesPlanStatScItemSDO = fetchBackSalesPlanStatScItemSDO(request);
        if (salesPlanStatScItemSDO.getOrganizationType().equals(request.getBizType()) || StringUtils.isBlank(salesPlanStatScItemSDO.getParentId())) {
            return buildPageQueryResult(request, salesPlanStatScItemSDO);
        }
        refreshRequest(request, salesPlanStatScItemSDO.getParentId());
        return pageQueryPlanScItemList(request);
    }

    private void refreshSalesPlanStatScItemSDO(List<SalesPlanStatScItemSDO> salesPlanStatScItemSDOS, Map<String, Boolean> reportMap) {
        if (CollectionUtils.isEmpty(salesPlanStatScItemSDOS)) {
            return;
        }
        salesPlanStatScItemSDOS.forEach(scItemSDO -> {
            if (StringUtils.isBlank(scItemSDO.getReportOrderId())) {
                scItemSDO.setIsAudit(false);
                return;
            }
            scItemSDO.setIsAudit(reportMap.getOrDefault(scItemSDO.getReportOrderId(), false));
        });
    }

    private Result<PageResult<List<SalesPlanStatScItemSDO>>> buildPageQueryResult(PageQueryPlanScItemStatRequest request, SalesPlanStatScItemSDO salesPlanStatScItemSDO) {
        return Result.success(PageResult.of(Lists.newArrayList(salesPlanStatScItemSDO), 1));
    }

    private void refreshRequest(PageQueryPlanScItemStatRequest request, String parentId) {
        request.setParentId(parentId);
    }

    private void checkPageQueryPlanScItemStatRequest(PageQueryPlanScItemStatRequest request) {
        if (null == request || StringUtils.isBlank(request.getParentId())) {
            throw new FacadeException(ErrorMessage.code("OTS-02-006-00-16-001"));
        }
        if (null == request.getBizType()) {
            throw new FacadeException(ErrorMessage.code("OTS-02-006-00-16-003"));
        }
        SalesStatBizTypeEnum salesStatBizTypeEnum = SalesStatBizTypeEnum.getByOrganizationType(request.getBizType());
        if (salesStatBizTypeEnum == null) {
            throw new FacadeException(ErrorMessage.code("OTS-02-006-00-16-002"));
        }
    }

    private SalesPlanStatScItemSDO fetchBackSalesPlanStatScItemSDO(PageQueryPlanScItemStatRequest request) {
        // 获取父级汇总数据
        QueryPlanScItemStatRequest queryPlanScItemStatRequest = new QueryPlanScItemStatRequest();
        queryPlanScItemStatRequest.setBizIds(Lists.newArrayList(request.getParentId()));
        queryPlanScItemStatRequest.setPlanId(Optional.ofNullable(request.getPlanId()).map(Long::parseLong).orElse(null));
        queryPlanScItemStatRequest.setPoolType(request.getPoolType().toString());
        queryPlanScItemStatRequest.setStart(0);
        queryPlanScItemStatRequest.setLimit(1000);
        PageResult<List<SalesPlanStatScItemSDO>> pageResult = salesPlanScItemStatRepository.batchQueryPlanScItemByBizId(queryPlanScItemStatRequest);
        if (null == pageResult || CollectionUtils.isEmpty(pageResult.getContent())) {
            throw new FacadeException(ErrorMessage.code("OTS-02-006-00-16-001"));
        }
        SalesPlanStatScItemSDO salesPlanStatScItemSDO = pageResult.getContent().get(0);
        SalesStatBizTypeEnum salesStatBizTypeEnum = SalesStatBizTypeEnum.match(salesPlanStatScItemSDO.getBizType());
        if (salesStatBizTypeEnum == null) {
            throw new FacadeException(ErrorMessage.code("OTS-02-006-00-16-002"));
        }
        if (salesStatBizTypeEnum.getOrganizationType() < request.getBizType()) {
            log.warn("已超出数据权限范围，无法显示数据");
            throw new FacadeException(ErrorMessage.code("OTS-02-006-00-16-001"));
        }
        salesPlanStatScItemSDO.setOrganizationType(salesStatBizTypeEnum.getOrganizationType());
        return salesPlanStatScItemSDO;
    }

    private void refreshSalesPlanStatScItemSDO(SalesPlanStatScItemSDO scItemSDO, PageQueryPlanScItemStatRequest request) {
        String modelId = request.getPlanId();
        Integer modelType = SalesPlanModelEnum.PLAN_MODEL.getModel();
        if (Boolean.TRUE.equals(request.getIsAdjustCount())) {
            modelId = request.getAdjustId();
            modelType = SalesPlanModelEnum.ADJUST_MODEL.getModel();
        }
        SalesPlanReportQueryRequest salesPlanReportQueryRequest = new SalesPlanReportQueryRequest();
        salesPlanReportQueryRequest.setModelId(modelId);
        salesPlanReportQueryRequest.setModelType(modelType);
        salesPlanReportQueryRequest.setBizId(scItemSDO.getBizId());
        salesPlanReportQueryRequest.setBizType(scItemSDO.getBizType());
        Result<SalesPlanReportSDO> salesPlanReportSDOResult = salesPlanReportQueryService.querySalesPlanReport(salesPlanReportQueryRequest);
        if (Objects.nonNull(salesPlanReportSDOResult.getResult())) {
            scItemSDO.setAuditStatus(salesPlanReportSDOResult.getResult().getAuditStatus());
            scItemSDO.setAuditStatusName(
                SalesPlanReportAuditStatusEnum.of(salesPlanReportSDOResult.getResult().getAuditStatus()).getDesc());
            scItemSDO.setReportStatus(salesPlanReportSDOResult.getResult().getStatus());
            scItemSDO.setReportStatusName(
                SalesPlanReportStatusEnum.of(salesPlanReportSDOResult.getResult().getStatus()).getDesc());
            scItemSDO.setReportOrderId(salesPlanReportSDOResult.getResult().getId());
        } else {
            scItemSDO.setAuditStatus(SalesPlanReportAuditStatusEnum.TO_BE_REVIEW.getCode());
            scItemSDO.setAuditStatusName(SalesPlanReportAuditStatusEnum.TO_BE_REVIEW.getDesc());
            scItemSDO.setReportStatus(SalesPlanReportStatusEnum.TO_REPORT.getCode());
            scItemSDO.setReportStatusName(SalesPlanReportStatusEnum.TO_REPORT.getDesc());
        }
    }

    private SalesPlanStatScItemSDO doCalculate(List<SalesPlanStatScItemSDO> salesPlanScItemStatSDOList) {
        SalesPlanStatScItemSDO salesPlanScItemStatSDO = new SalesPlanStatScItemSDO();
        Integer taskCountSum = salesPlanScItemStatSDOList.stream().mapToInt(SalesPlanStatScItemSDO::getTaskCount).sum();
        // Integer returnCountSum = salesPlanScItemStatSDOList.stream().mapToInt(SalesPlanStatScItemSDO::getReturnCount).sum();
        Integer monthFirstReturnCountSum = salesPlanScItemStatSDOList.stream().mapToInt(SalesPlanStatScItemSDO::getMonthFirstReturnCount).sum();
        Integer monthFirstTaskCountSum = salesPlanScItemStatSDOList.stream().mapToInt(SalesPlanStatScItemSDO::getMonthFirstTaskCount).sum();
        Integer monthMiddleReturnCountSum = salesPlanScItemStatSDOList.stream().mapToInt(SalesPlanStatScItemSDO::getMonthMiddleReturnCount).sum();
        Integer monthMiddleTaskCountSum = salesPlanScItemStatSDOList.stream().mapToInt(SalesPlanStatScItemSDO::getMonthMiddleTaskCount).sum();
        Integer monthLastReturnCountSum = salesPlanScItemStatSDOList.stream().mapToInt(SalesPlanStatScItemSDO::getMonthLastReturnCount).sum();
        Integer monthLastTaskCountSum = salesPlanScItemStatSDOList.stream().mapToInt(SalesPlanStatScItemSDO::getMonthLastTaskCount).sum();
        salesPlanScItemStatSDO.setTaskCount(taskCountSum);
        // salesPlanScItemStatSDO.setReturnCount(returnCountSum);
        salesPlanScItemStatSDO.setMonthFirstReturnCount(monthFirstReturnCountSum);
        salesPlanScItemStatSDO.setMonthFirstTaskCount(monthFirstTaskCountSum);
        salesPlanScItemStatSDO.setMonthMiddleTaskCount(monthMiddleTaskCountSum);
        salesPlanScItemStatSDO.setMonthMiddleReturnCount(monthMiddleReturnCountSum);
        salesPlanScItemStatSDO.setMonthLastTaskCount(monthLastTaskCountSum);
        salesPlanScItemStatSDO.setMonthLastReturnCount(monthLastReturnCountSum);
        return salesPlanScItemStatSDO;
    }

    /**
     * 部门提报量分解- 查询部门汇总提报量
     *
     * @param request
     * @return
     */
    @Override
    public Result<List<DepartmentResponse>> dimensionGoodsQueryDepartment(PageQueryPlanScItemStatRequest request) {
        //校验入参
        if (StringUtils.isBlank(request.getPlanId())) {
            throw new FacadeException("OTS-02-001-00-15-006");
        }
        if (StringUtils.isBlank(request.getScItemId())) {
            throw new FacadeException("OTS-01-005-02-15-012");
        }
        if (Objects.isNull(request.getPoolType())) {
            throw new FacadeException("OTS-02-004-01-15-002");
        }
        //根据当前：货品ID+月度计划ID+汇总类型(货品汇总)+数据维度类型(部门维度) 查询出当前货品归属哪些部门下
        Result<List<PlanScItem>> listResult = planScItemService.loadPlanScItemList(LoadPlanScItemListRequest.builder()
                .planId(request.getPlanId())
                .scItemId(request.getScItemId())
                .poolType(request.getPoolType())
                .bizType(SalesStatBizTypeEnum.SALES_DEPARTMENT.getBizType())
                .build());
        if (CollectionUtils.isEmpty(listResult.getResult())) {
            throw new FacadeException("OTS-05-001-10-16-022");
        }
        //获取当前货品归属于哪些部门  并每个部门分别提报量为多少（monthCount）
        Map<String, Integer> departmentKeyValuePair = listResult.getResult().stream().filter(t -> t.getBizId() != null).collect(Collectors.toMap(PlanScItem::getBizId, PlanScItem::getMonthCount, (k1, k2) -> k1));
        //取出所有的Key(BizId)进行转换成部门名称
        Set<String> departmentKey = departmentKeyValuePair.keySet();
        //List<String> departmentKey = (List<String>) strings;
        BaselineGetOrganizationByIdsAllResponse organization = baseDataService.baselineGetOrganizationByIdsAll(BaselineGetOrganizationByIdsAllRequest.builder().ids(Arrays.asList(departmentKey.toArray())).build());
        if (CollectionUtils.isEmpty(organization.getResult())) {
            throw new FacadeException("OTS-01-004-02-15-004");
        }
        //构建一个新MAP进行 名称替换掉ID 返回
        List<DepartmentResponse> departmentResponse = new ArrayList<>();
        //Map<String, Integer> valueOfDepartment = new HashMap<>();
        for (OrganizationSDO organizationSDO : organization.getResult()) {
            DepartmentResponse departmentResponse1 = new DepartmentResponse();
            departmentResponse1.setName(organizationSDO.getName());
            departmentResponse1.setMonthCount(departmentKeyValuePair.get(organizationSDO.getId()));
            departmentResponse1.setBizId(organizationSDO.getId());
            //valueOfDepartment.put(organizationSDO.getName(), departmentKeyValuePair.get(organizationSDO.getId()));
            departmentResponse.add(departmentResponse1);
        }
        return Result.success(departmentResponse);
    }

    /**
     * 渠道提报量分解- 查询渠道汇总提报量
     *
     * @param request
     * @return
     */
    @Override
    public Result<List<DepartmentResponse>> dimensionGoodsQueryChannel(PageQueryPlanScItemStatRequest request) {
        //校验入参
        if (StringUtils.isBlank(request.getPlanId())) {
            throw new FacadeException("OTS-02-001-00-15-006");
        }
        if (StringUtils.isBlank(request.getScItemId())) {
            throw new FacadeException("OTS-01-005-02-15-012");
        }
        if (Objects.isNull(request.getPoolType())) {
            throw new FacadeException("OTS-02-004-01-15-002");
        }
        //根据当前：货品ID+月度计划ID+汇总类型(货品汇总)+数据维度类型(渠道维度) 查询出当前货品归属哪些渠道下
        Result<List<PlanScItem>> listResult = planScItemService.loadPlanScItemList(LoadPlanScItemListRequest.builder()
                .planId(request.getPlanId())
                .scItemId(request.getScItemId())
                .poolType(request.getPoolType())
                .bizType(SalesStatBizTypeEnum.SALES_CHANNEL.getBizType())
                .build());
        if (CollectionUtils.isEmpty(listResult.getResult())) {
            throw new FacadeException("OTS-05-001-10-16-022");
        }
        //获取当前货品归属于哪些渠道  并每个部门分别提报量为多少（monthCount）
        Map<String, Integer> channelKeyValuePair = listResult.getResult().stream().filter(t -> t.getBizId() != null).collect(Collectors.toMap(PlanScItem::getBizId, PlanScItem::getMonthCount, (k1, k2) -> k1));
        //取出所有的Key(BizId)进行转换成渠道名称
        Set<String> channelKey = channelKeyValuePair.keySet();
        //List<String> departmentKey = (List<String>) strings;
        BaselineGetOrganizationByIdsAllResponse organization = baseDataService.baselineGetOrganizationByIdsAll(BaselineGetOrganizationByIdsAllRequest.builder().ids(Arrays.asList(channelKey.toArray())).build());
        if (CollectionUtils.isEmpty(organization.getResult())) {
            throw new FacadeException("OTS-01-004-02-15-004");
        }
        //构建一个新MAP进行 名称替换掉ID 返回
        List<DepartmentResponse> departmentResponse = new ArrayList<>();
        //Map<String, Integer> valueOfDepartment = new HashMap<>();
        for (OrganizationSDO organizationSDO : organization.getResult()) {
            DepartmentResponse departmentResponse1 = new DepartmentResponse();
            departmentResponse1.setName(organizationSDO.getName());
            departmentResponse1.setMonthCount(channelKeyValuePair.get(organizationSDO.getId()));
            departmentResponse1.setBizId(organizationSDO.getId());
            //valueOfDepartment.put(organizationSDO.getName(), departmentKeyValuePair.get(organizationSDO.getId()));
            departmentResponse.add(departmentResponse1);
        }
        return Result.success(departmentResponse);
    }

    /**
     * 部门调整量分解- 查询部门汇总任务量
     * @param request
     * @return
     */
    @Override
    public Result<List<DepartmentResponse>> dimensionGoodsQueryDepartmentAdjust(PageQueryPlanScItemStatRequest request) {
        //校验入参
        if (StringUtils.isBlank(request.getPlanId())) {
            throw new FacadeException("OTS-02-001-00-15-006");
        }
        if (StringUtils.isBlank(request.getScItemId())) {
            throw new FacadeException("OTS-01-005-02-15-012");
        }
        if (Objects.isNull(request.getPoolType())) {
            throw new FacadeException("OTS-02-004-01-15-002");
        }
        //根据当前：货品ID+月度计划ID+汇总类型(货品汇总)+数据维度类型(部门维度) 查询出当前货品归属哪些部门下
        Result<List<PlanScItem>> listResult = planScItemService.loadPlanScItemList(LoadPlanScItemListRequest.builder()
                .planId(request.getPlanId())
                .scItemId(request.getScItemId())
                .poolType(request.getPoolType())
                .bizType(SalesStatBizTypeEnum.SALES_DEPARTMENT.getBizType())
                .build());
        if (CollectionUtils.isEmpty(listResult.getResult())) {
            throw new FacadeException("OTS-05-001-10-16-022");
        }
        //获取当前货品归属于哪些部门  并每个部门分别任务量为多少
        List<PlanScItem> filterList = listResult.getResult().stream().filter(t -> t.getBizId() != null).collect(Collectors.toList());
        Map<String, PlanScItem> departmentKeyPlanScItem = filterList.stream().collect(Collectors.toMap(PlanScItem::getBizId, Function.identity(), (k1, k2) -> k1));

        //取出所有的Key(BizId)进行转换成部门名称
        Set<String> departmentKey = departmentKeyPlanScItem.keySet();
        BaselineGetOrganizationByIdsAllResponse organization = baseDataService.baselineGetOrganizationByIdsAll(BaselineGetOrganizationByIdsAllRequest.builder().ids(Arrays.asList(departmentKey.toArray())).build());
        if (CollectionUtils.isEmpty(organization.getResult())) {
            throw new FacadeException("OTS-01-004-02-15-004");
        }
        //构建一个新MAP进行 名称替换掉ID 返回
        List<DepartmentResponse> departmentResponse = new ArrayList<>();
        for (OrganizationSDO organizationSDO : organization.getResult()) {
            DepartmentResponse departmentResponse1 = new DepartmentResponse();
            departmentResponse1.setName(organizationSDO.getName());
            PlanScItem planScItem = departmentKeyPlanScItem.get(organizationSDO.getId());
            departmentResponse1.setTaskCount(planScItem.getTaskCount());
            departmentResponse1.setMonthFirstTaskCount(planScItem.getMonthFirstTaskCount());
            departmentResponse1.setMonthMiddleTaskCount(planScItem.getMonthMiddleTaskCount());
            departmentResponse1.setMonthLastTaskCount(planScItem.getMonthLastTaskCount());
            departmentResponse1.setAdjustCount(planScItem.getAdjustCount());
            departmentResponse1.setMonthFirstAdjustCount(planScItem.getMonthFirstAdjustCount());
            departmentResponse1.setMonthMiddleAdjustCount(planScItem.getMonthMiddleAdjustCount());
            departmentResponse1.setMonthLastAdjustCount(planScItem.getMonthLastAdjustCount());
            departmentResponse1.setBizId(organizationSDO.getId());
            departmentResponse.add(departmentResponse1);
        }
        return Result.success(departmentResponse);
    }

    /**
     * 渠道调整量分解- 查询渠道汇总任务量
     * @param request
     * @return
     */
    @Override
    public Result<List<DepartmentResponse>> dimensionGoodsQueryChannelAdjust(PageQueryPlanScItemStatRequest request) {
        //校验入参
        if (StringUtils.isBlank(request.getPlanId())) {
            throw new FacadeException("OTS-02-001-00-15-006");
        }
        if (StringUtils.isBlank(request.getScItemId())) {
            throw new FacadeException("OTS-01-005-02-15-012");
        }
        if (Objects.isNull(request.getPoolType())) {
            throw new FacadeException("OTS-02-004-01-15-002");
        }
        //根据当前：货品ID+月度计划ID+汇总类型(货品汇总)+数据维度类型(渠道维度) 查询出当前货品归属哪些渠道下
        Result<List<PlanScItem>> listResult = planScItemService.loadPlanScItemList(LoadPlanScItemListRequest.builder()
                .planId(request.getPlanId())
                .scItemId(request.getScItemId())
                .poolType(request.getPoolType())
                .bizType(SalesStatBizTypeEnum.SALES_CHANNEL.getBizType())
                .build());
        if (CollectionUtils.isEmpty(listResult.getResult())) {
            throw new FacadeException("OTS-05-001-10-16-022");
        }
        //获取当前货品归属于哪些渠道  并每个渠道分别任务量为多少
        List<PlanScItem> filterList = listResult.getResult().stream().filter(t -> t.getBizId() != null).collect(Collectors.toList());
        Map<String, PlanScItem> channelKeyPlanScItem = filterList.stream().collect(Collectors.toMap(PlanScItem::getBizId, Function.identity(), (k1, k2) -> k1));

        //取出所有的Key(BizId)进行转换成渠道名称
        Set<String> channelKey = channelKeyPlanScItem.keySet();
        BaselineGetOrganizationByIdsAllResponse organization = baseDataService.baselineGetOrganizationByIdsAll(BaselineGetOrganizationByIdsAllRequest.builder().ids(Arrays.asList(channelKey.toArray())).build());
        if (CollectionUtils.isEmpty(organization.getResult())) {
            throw new FacadeException("OTS-01-004-02-15-004");
        }
        //构建一个新MAP进行 名称替换掉ID 返回
        List<DepartmentResponse> departmentResponse = new ArrayList<>();
        for (OrganizationSDO organizationSDO : organization.getResult()) {
            DepartmentResponse channelResponse1 = new DepartmentResponse();
            channelResponse1.setName(organizationSDO.getName());
            PlanScItem planScItem = channelKeyPlanScItem.get(organizationSDO.getId());
            channelResponse1.setTaskCount(planScItem.getTaskCount());
            channelResponse1.setMonthFirstTaskCount(planScItem.getMonthFirstTaskCount());
            channelResponse1.setMonthMiddleTaskCount(planScItem.getMonthMiddleTaskCount());
            channelResponse1.setMonthLastTaskCount(planScItem.getMonthLastTaskCount());
            channelResponse1.setAdjustCount(planScItem.getAdjustCount());
            channelResponse1.setMonthFirstAdjustCount(planScItem.getMonthFirstAdjustCount());
            channelResponse1.setMonthMiddleAdjustCount(planScItem.getMonthMiddleAdjustCount());
            channelResponse1.setMonthLastAdjustCount(planScItem.getMonthLastAdjustCount());
            channelResponse1.setBizId(organizationSDO.getId());
            departmentResponse.add(channelResponse1);
        }
        return Result.success(departmentResponse);
    }
}
